#include <string.h>
#include <stdarg.h>

#include "FreeRTOS.h"
#include "task.h"

#include "SEGGER_RTT.h"
#include "app_fifo.h"
//#include "nrf_atomic.h"

#include "at_lexer.h"
#include "drv_net_port.h"
#include "drv_net.h"
#include "drv_bc26.h"
#include "drv_ft780.h"
#include "drv_m5310a.h"
#include "drv_m5313.h"
#include "drv_a9600.h"
#include "drv_s800c.h"
#include "misc.h"







ENV_NET env_net;



int32_t drv_net_install(void) {
    return drv_net_port_install();
}

int32_t drv_net_uninstall(void) {
    return drv_net_port_uninstall();
}

void drv_net_power_on(void) {
    NET_RST_DISABLE();
    NET_RUN_DISABLE();
    NET_PWR_DISABLE();
    NET_TR_ENABLE();
    NET_INT_DISABLE();
    vTaskDelay(500);

    NET_PWR_ENABLE();
    vTaskDelay(500);

    NET_RST_ENABLE();
    vTaskDelay(1000);
    NET_RST_DISABLE();


    NET_INF("run....\r\n");
    NET_RUN_ENABLE();
    vTaskDelay(3000);
    NET_INF("run\r\n");
    NET_RUN_DISABLE();
    vTaskDelay(1000);


//    NET_RST_DISABLE();
//    NET_RUN_DISABLE();
//    NET_PWR_DISABLE();
//    NET_TR_DISABLE();
//    NET_INT_DISABLE();
}

void drv_net_power_off(void) {
    NET_PWR_DISABLE();
    NET_TR_ENABLE();
    NET_RST_DISABLE();
    NET_RUN_DISABLE();
    NET_INT_ENABLE();
}

void drv_net_power_wake_up(void) {
    NET_INT_ENABLE();
    vTaskDelay(200);
    NET_INT_DISABLE();
}



void drv_net_result_ok(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.result = AT_RESULT_OK;
    if (xQueueSend(env_net.qresult, &msg_at, 200) != pdPASS) {
        NET_ERR("fail to pass the result");
    }
}




void drv_net_result_error(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.result = AT_RESULT_ERROR;
    if (xQueueSend(env_net.qresult, &msg_at, 200) != pdPASS) {
        NET_ERR("fail to pass the result");
    }
}

int32_t drv_net_any(uint8_t *pdata, uint32_t len) {
    return -1;
}


NET_ERR_CODE drv_net_write_bytes_raw(uint32_t timeout, uint32_t retry, uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    uint32_t i;
    while (retry--) {
        NET_PUTCHAR('-');
        NET_PUTCHAR('-');
        NET_PUTCHAR('>');
        for (i = 0; i < len; i++) {
            NET_PUTCHAR(pdata[i]);
        }
        NET_PUTCHAR('\n');
        if (xSemaphoreTake(env_net.sem_at, 15000) != pdPASS) {
            NET_ERR("failed to take sem_at");
            return NET_ERR_UNKOWN;
        }
        xQueueReset(env_net.qresult);   /** Since FreeRTOS V7.2.0 xQueueReset() always returns pdPASS */
        if (drv_net_port_uart_write_bytes(pdata, len)) {
            NET_ERR("failed to write bytes");
            xSemaphoreGive(env_net.sem_at);
            return NET_ERR_UART;
        }
        if (xQueueReceive(env_net.qresult, &msg_at, timeout) == pdPASS) {
            xSemaphoreGive(env_net.sem_at);
            if (msg_at.result == AT_RESULT_OK) {
                return NET_ERR_OK;
            } else if (msg_at.result == AT_RESULT_ERROR) {
                NET_ERR("at result");
                return NET_ERR_AT;
            } else {
                NET_ERR("unkown result:%08x", msg_at.result);
                return NET_ERR_UNKOWN;
            }
        } else {
            xSemaphoreGive(env_net.sem_at);
        }
    }

    NET_ERR("net module might be broken,sleeping or powered off");
    return NET_ERR_STATE;
}

void drv_net_m5310a(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_M5310A;
    NET_INF("I'm m5310a");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

void drv_net_bc26(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_BC26;
    NET_INF("I'm bc26");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

void drv_net_ft780(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_FT780;
    NET_INF("I'm ft780");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

void drv_net_m5313(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_M5313;
    NET_INF("I'm m5313");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

void drv_net_a9600(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_A9600;
    NET_INF("I'm a9600");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

void drv_net_s800c(uint8_t *pdata, uint32_t len) {
    MSG_AT msg_at;
    msg_at.info = AT_INFO_CGMM;
    msg_at.value = DRV_NET_DEVICE_S800C;
    NET_INF("I'm s800c");
    if (xQueueSend(env_net.qinfo, &msg_at, 200) != pdPASS) {
        NET_ERR("failed to pass the result");
    }
}

DRV_NET_CARRIER drv_net_find_carrier_by_imsi(const char *pimsi) {
    if (strncmp(pimsi, "46004", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CM;
    } else if (strncmp(pimsi, "46002", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CM;
    } else if (strncmp(pimsi, "46000", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CM;
    } else if (strncmp(pimsi, "46007", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CM;
    } else if (strncmp(pimsi, "46011", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CT;
    } else if (strncmp(pimsi, "46003", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CT;
    } else if (strncmp(pimsi, "46005", sizeof("460xx") - 1) == 0) {
        return DRV_NET_CARRIER_CT;
    } else { //unkown
        return DRV_NET_CARRIER_MAX;
    }
}

AT_HANDLER drv_net_at_handlers[] = {
    AT_HANDLER_GENERAL_DEF("OK", drv_net_result_ok),
    AT_HANDLER_GENERAL_DEF("ERROR", drv_net_result_error),
    AT_HANDLER_GENERAL_DEF("M5310-A", drv_net_m5310a),
    AT_HANDLER_GENERAL_DEF("Quectel_BC26", drv_net_bc26),
    AT_HANDLER_GENERAL_DEF("ZXIC-MDL", drv_net_ft780),
    AT_HANDLER_GENERAL_DEF("M5313", drv_net_m5313),
    AT_HANDLER_GENERAL_DEF("A9600", drv_net_a9600),
    AT_HANDLER_GENERAL_DEF("SIMCOM_SIM800C", drv_net_s800c),
    AT_HANDLER_ANY(drv_net_any)
};

NET_ERR_CODE drv_net_scan_device_type(DRV_NET_DEVICE *pdevice_type) {
    NET_ERR_CODE ret;
    MSG_AT msg_at;
    uint32_t i;
    drv_net_power_on();
    env_net.pat_handlers = drv_net_at_handlers;
    *pdevice_type = DRV_NET_DEVICE_MAX;

    if(drv_net_write_bytes_raw(1000,3,TSTRING(uint8_t *,"AT\r")) < 0){
        /** m5313's default baudrate is 57600 */
        if (drv_net_port_uart_baudrate_change(57600) < 0) {
            return NET_ERR_UNKOWN;
        }
        if (drv_net_write_bytes_raw(1000,3,TSTRING(uint8_t *,"AT\r")) < 0) { //not m5313?
            if (drv_net_port_uart_baudrate_change(9600) < 0) { //restore the baudrate
                return NET_ERR_UNKOWN;
            }
            if (drv_net_write_bytes_raw(1000,10,TSTRING(uint8_t *,"AT\r")) < 0) { //not ft780?
                NET_ERR("net module might be broken");
                return NET_ERR_UNKOWN;
            }
        } else {
            //do nothing
            //change baudrate to 9600?
        }
    }
    //AT+CGMM
    xQueueReset(env_net.qinfo);
    ret = drv_net_write_bytes_raw(1000,1,TSTRING(uint8_t *,"AT+CGMM\r"));
    if (ret < 0) {
        NET_ERR("");
        return ret;
    }
    for (i = 5; i > 0; i--) {
        if (xQueueReceive(env_net.qinfo, &msg_at, 1000) == pdPASS) {
            if (msg_at.info == AT_INFO_CGMM) {
                *pdevice_type = (DRV_NET_DEVICE)msg_at.value;
                NET_INF("net device type is %d", msg_at.value);
                break;
            }
        } else if (i == 1) {
            NET_INF("scan net device timeout");
            return NET_ERR_UNKOWN;
        }
    }
    return NET_ERR_OK;
}


PF_AT_LEXER_STATE drv_net_lexer_handler(uint8_t *pdata, uint32_t len) {
    uint32_t i;
    AT_HANDLER *phandler = env_net.pat_handlers;
    //show at response
//    NET_PUTCHAR('{');
//    NET_PUTCHAR('[');
//    for(i = 0;i < len;i++){
//        NET_PUTCHAR(pdata[i]);
//    }
//    NET_PUTCHAR(']');
//    NET_PUTCHAR('}');
//    NET_PUTCHAR('\r');
//    NET_PUTCHAR('\n');
    //response callback

    if (phandler == NULL) {
        NET_WAR("at_handlers is not set");
        return NULL;
    }
    while (phandler->size) {
        if (len >= phandler->size) {
            if (!str_cmp((const char *)pdata, phandler->size, phandler->pname, phandler->size)) { //macth?
                phandler->nb_info_handler(pdata + phandler->size, len - phandler->size);
                return phandler->pf_at_lexer_state;
            }
        }
        phandler++;
    }
    if ((*pdata == '+') || (phandler->nb_info_handler_any(pdata, len) != 0)) {
        NET_WAR("unkown AT response:");
        for (i = 0; i < len; i++) {
            NET_PUTCHAR(pdata[i]);
        }
        NET_PUTCHAR('\r');
        NET_PUTCHAR('\n');
    }
    return NULL;
}

void drv_net_task_uart_receive(void *parg) {
    uint8_t data;
    drv_net_port_uart_rx_start();
//    env_net.pat_handlers = drv_bc26_at_handlers;
//    env_net.pat_handlers = drv_ft780_at_handlers;
//    env_net.pat_handlers = drv_m5310a_at_handlers;
    at_lexer_handler_set(drv_net_lexer_handler);
    while (1) {
        if (drv_net_port_uart_read_byte(&data)) {
            vTaskDelay(100);
            continue;
        }
#if 0
        switch(data){
            case '\r':
            NET_PUTCHAR('#');
            break;
            case '\n':
            NET_PUTCHAR('*');
            break;
            default:
            NET_PUTCHAR(data);
        }
#else
        NET_PUTCHAR(data);
#endif
        at_lexer_execute(data);
    }
}


void drv_net_task_msg_recv(void *parg) {
    MSG_RECV msg_recv;
    while (1) {
        if (xQueueReceive(env_net.qrecv, &msg_recv, 100) != pdPASS) {
            continue;
        }
        drv_bc26_recv_excute(&msg_recv);
    }
}

NET_ERR_CODE drv_net_fifo_init(app_fifo_t *papp_fifo, uint32_t fifo_size) {
    if (papp_fifo == NULL) {
        return NET_ERR_UNKOWN;
    }
    if (!IS_POWER_OF_TWO(fifo_size)) {
        NET_ERR("fifo_size is not power of two");
        return NET_ERR_UNKOWN;
    }
    if (papp_fifo->p_buf == NULL) {
        papp_fifo->p_buf = pvPortMalloc(fifo_size);
        if (papp_fifo->p_buf == NULL) {
            NET_ERR("failed to alloc fifo buffer");
            return NET_ERR_UNKOWN;
        }
        papp_fifo->buf_size_mask = fifo_size - 1;
        papp_fifo->read_pos      = 0;
        papp_fifo->write_pos     = 0;
    }
    return NET_ERR_OK;
}

void drv_net_connections_init(void) {
    uint32_t i;
    for (i = 0; i < DRV_NET_MAX_NUM_OF_CONNECTIONS; i++) {
        env_net.pconns[i].socket = -1;
    }
}

app_fifo_t fifo_upgrade;
int32_t drv_net_init(void) {
	drv_net_fifo_init(&fifo_upgrade,2048);
	
    if (drv_net_port_ctrl_init()) {
        return -1;
    }
    if (drv_net_port_uart_init()) {
        return -1;
    }
    memset(&env_net, 0, sizeof(ENV_NET)); //clear

    drv_net_connections_init();

    env_net.device = DRV_NET_DEVICE_MAX;

//    env_net.csi = 0xFFFFFFFF;

    env_net.qresult = xQueueCreate(3, sizeof(MSG_AT));
    if (env_net.qresult == NULL) {
        NET_ERR("failed to create result queue");
        return -1;
    }
    env_net.qinfo = xQueueCreate(5, sizeof(MSG_AT));
    if (env_net.qinfo  == NULL) {
        NET_ERR("failed to create info queue");
        return -1;
    }
    env_net.qrecv = xQueueCreate(5, sizeof(MSG_RECV));
    if (env_net.qrecv == NULL) {
        NET_ERR("failed to create recv queue");
        return -1;
    }
    env_net.sem_at = xSemaphoreCreateMutex();
    if (env_net.sem_at == NULL) {
        NET_ERR("failed to creat at mutex");
        return -1;
    }

    env_net.sem_send = xSemaphoreCreateMutex();
    if (env_net.sem_send == NULL) {
        NET_ERR("failed to create send mutex");
        return -1;
    }

    env_net.pif_devices[DRV_NET_DEVICE_BC26] = &drv_bc26_interface;
    env_net.pif_devices[DRV_NET_DEVICE_FT780] = &drv_ft780_interface;
    env_net.pif_devices[DRV_NET_DEVICE_M5310A] = &drv_m5310a_interface;
    env_net.pif_devices[DRV_NET_DEVICE_M5313] = &drv_m5313_interface;
    env_net.pif_devices[DRV_NET_DEVICE_A9600] = &drv_a9600_interface;
    env_net.pif_devices[DRV_NET_DEVICE_S800C] = &drv_s800c_interface;
    return 0;
}

const DRV_NET_INTERFACE* drv_net_find_if(DRV_NET_DEVICE device_type) {
    if (!BETWEEN10(0, (int32_t)device_type, DRV_NET_DEVICE_MAX)) {
        return NULL;
    }
    return env_net.pif_devices[device_type];
}

NET_ERR_CODE drv_net_configure(DRV_NET_SERVICE service,
                               char *pserver_ip,
                               char *pserver_port,
                               uint32_t fifo_size) {
//auto
#if 0
    env_net.device = device;
    env_net.carrier = carrier;
#endif
    env_net.service = service;
    if ((pserver_ip == NULL) || (env_net.pserver_port == NULL)) {
        env_net.pserver_ip = pserver_ip;
        env_net.pserver_port = pserver_port;
    } else {
        strcpy(env_net.pconns[0].paddr, pserver_ip);
        strcpy(env_net.pconns[0].pport, pserver_port);
        env_net.pserver_ip = env_net.pconns[0].paddr;
        env_net.pserver_port = env_net.pconns[0].pport;
    }
    env_net.fifo_size = fifo_size;
    return NET_ERR_OK;
}

static int drv_net_power_ctrl_check(NET_POWER_CONTROL ctrl) {
    if (env_net.state >= NET_STATE_MAX) {
        if (ctrl != NET_POWER_OFF) {
            NET_ERR("invalid state %d", env_net.state);
            return -1; //error
        }
    }
    if (ctrl == NET_POWER_ON) {
        if (env_net.state == NET_STATE_READY) {
            NET_WAR("the module is already on");
            return 1; //keep
        } else if (env_net.state == NET_STATE_SLEEP) {
            NET_ERR("power on the module from psm");
            return -1; //error
        } else { //NET_STATE_OFF --> NET_STATE_READY
            return 0; //change
        }
    } else if (ctrl == NET_POWER_SLEEP) {
        if (env_net.state == NET_STATE_SLEEP) {
            NET_WAR("the module is already sleeping");
            return 1;
        } else if (env_net.state == NET_STATE_OFF) {
            NET_ERR("module which is off can't enter psm ");
            return -1;
        } else { //NET_STATE_READY --> NET_STATE_SLEEP
            return 0;
        }
    } else if (ctrl == NET_POWER_OFF) {
        if (env_net.state == NET_STATE_SLEEP) {
            NET_WAR("power off the module from psm");
            return 0;
        } else if (env_net.state == NET_STATE_OFF) {
            NET_WAR("the module is already off");
            return 0;
        } else { //NET_STATE_ON or others
            return 0;
        }
    } else if (ctrl == NET_POWER_WAKE) {
        if (env_net.state == NET_STATE_READY) {
            NET_WAR("wake up the module from ready");
            return 1;
        } else if (env_net.state == NET_STATE_SLEEP) { //NET_STATE_SLEEP --> NET_STATE_READY
            return 0;
        } else { //NET_STATE_OFF
            NET_ERR("try to wake up module which isn't sleeping");
            return -1; //error
        }
    } else {
        NET_ERR("invalid power ctrl code %d", ctrl);
        return -1; //error
    }
}


NET_STATE drv_net_state_get(void) {
    return env_net.state;
}


char* drv_net_imei_get(void) {
	if(env_net.pimei[0]!=0)
		return env_net.pimei;
	return NULL;
}
char* drv_net_imsi_get(void) {
    if(env_net.pimsi[0]!=0) 
        return env_net.pimsi;
	return NULL; 
}
char* drv_net_qccid_get(void) {
    if(env_net.qccid[0]!=0) 
        return env_net.qccid;
	return NULL; 
}
DRV_NET_DEVICE drv_net_device_get(void) {
    if (env_net.state == NET_STATE_OFF) {
        NET_WAR("read device type when the module is powered off");
    }
    return env_net.device;
}

NET_ERR_CODE drv_net_sq_get(uint32_t *psq) {
    NET_ERR_CODE ret;
    const DRV_NET_INTERFACE *pif;
    if (psq == NULL) {
        NET_ERR("null pointer");
        return NET_ERR_UNKOWN;
    }
    if (env_net.state != NET_STATE_READY) {
        *psq = env_net.sq;
        return NET_ERR_OK;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device %d", env_net.device);
        xSemaphoreGive(env_net.sem_send);
        *psq = 0;
        return NET_ERR_UNKOWN;
    }
    if (pif->pf_executor == NULL) {
        NET_ERR("device %d doesn't support executor", env_net.device);
        xSemaphoreGive(env_net.sem_send);
        *psq = 0;
        return NET_ERR_UNKOWN;
    }
    ret = pif->pf_executor(NET_CMD_SQ_GET, psq);
    xSemaphoreGive(env_net.sem_send);
    return ret;
}


NET_CT_ID_TYPE drv_net_ct_id_type(void) {
    NET_CT_ID_TYPE ct_id_type;
    const DRV_NET_INTERFACE *pif;
    if (env_net.state != NET_STATE_READY && env_net.state != NET_STATE_SLEEP) {
        return NET_CT_ID_MAX;
    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device type %d", env_net.device);
        return NET_CT_ID_MAX;
    }
    if (pif->pf_executor == NULL) {
        NET_ERR("device %d doesn't support executor",env_net.device);
        return NET_CT_ID_MAX;
    }
    pif->pf_executor(NET_CMD_CT_ID_TYPE_GET,&ct_id_type);
    return ct_id_type;
}

NET_ERR_CODE drv_net_cell_inf_get(CELL_INF *pcell_inf) {
    const DRV_NET_INTERFACE *pif;
    if (env_net.state != NET_STATE_READY && env_net.state != NET_STATE_SLEEP) {
        return NET_ERR_UNKOWN;
    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device type %d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    if (pif->pf_executor == NULL) {
        NET_ERR("device %d doesn't support executor",env_net.device);
        return NET_ERR_UNKOWN;
    }
    return pif->pf_executor(NET_CMD_CELL_INF_GET,pcell_inf);
}

NET_ERR_CODE drv_net_date_info_get(NET_DATE_T *t) {
    const DRV_NET_INTERFACE *pif;
    if (env_net.state != NET_STATE_READY && env_net.state != NET_STATE_SLEEP) {
        return NET_ERR_UNKOWN;
    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device type %d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    if (pif->pf_executor == NULL) {
        NET_ERR("device %d doesn't support executor",env_net.device);
        return NET_ERR_UNKOWN;
    }
    return pif->pf_executor(NET_CMD_CCLK_TIME_GET, t);
}

bool drv_net_support_cm(void) {
    const DRV_NET_INTERFACE *pif;
//    if (env_net.state != NET_STATE_READY && env_net.state != NET_STATE_SLEEP) {
//        NET_ERR("net module isn't ready");
//        return false;
//    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device type %d",env_net.device);
        return false;
    }
    if (pif->pf_cm_connect == NULL) {
        return false;
    } else {
        return true;
    }
}

bool drv_net_support_ct(void) {
    const DRV_NET_INTERFACE *pif;
//    if (env_net.state != NET_STATE_READY && env_net.state != NET_STATE_SLEEP) {
//        NET_ERR("net module isn't ready");
//        return false;
//    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("unkown device type %d",env_net.device);
        return false;
    }
    if (pif->pf_ct_connect == NULL) {
        return false;
    } else {
        return true;
    }
}

NET_ERR_CODE drv_net_power_set(NET_POWER_CONTROL ctrl) {
    NET_ERR_CODE ret = NET_ERR_UNKOWN;
    int32_t state_check_result;
    const DRV_NET_INTERFACE *pif;
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    state_check_result = drv_net_power_ctrl_check(ctrl);
    if (state_check_result < 0) { //error
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_STATE;
    } else if (state_check_result > 0) { //keep
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_OK;
    } else { //change
    }
    if (ctrl == NET_POWER_ON) {
        if (drv_net_scan_device_type(&(env_net.device)) != NET_ERR_OK) {
            NET_ERR("unkown net device");
            xSemaphoreGive(env_net.sem_send);
            return NET_ERR_UNKOWN;
        }
    }
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    if (pif->pf_power_set) {
        ret = pif->pf_power_set(ctrl);
    } else {
        NET_ERR("device %d not support power set", env_net.device);
    }
    if (ret == NET_ERR_OK) {
        if (ctrl == NET_POWER_OFF) {
            env_net.state = NET_STATE_OFF;
        } else if (ctrl == NET_POWER_ON || ctrl == NET_POWER_WAKE) {
            env_net.state = NET_STATE_READY;
        } else if (ctrl == NET_POWER_SLEEP) {
            env_net.state = NET_STATE_SLEEP;
        }
    } else {
        if (ctrl == NET_POWER_ON) { //failed to get ip
            env_net.state = NET_STATE_OFF;
        }
    }
    xSemaphoreGive(env_net.sem_send);
    return ret;
}


NET_ERR_CODE drv_net_connect(void) {
    NET_ERR_CODE ret = NET_ERR_UNKOWN;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    if (env_net.service == DRV_NET_SERVICE_CM) {
        if (pif->pf_cm_connect) {
            ret = pif->pf_cm_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if (env_net.service == DRV_NET_SERVICE_CT) {
        if (pif->pf_ct_connect) {
            ret = pif->pf_ct_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if (env_net.service == DRV_NET_SERVICE_TCP) {
        if (pif->pf_socket_connect) {
            ret = pif->pf_socket_connect(0, DRV_NET_SOCKET_TCP, env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if (env_net.service == DRV_NET_SERVICE_UDP) {
        if (pif->pf_socket_connect) {
            ret = pif->pf_socket_connect(0, DRV_NET_SOCKET_UDP, env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else {
        NET_ERR("invalid service:%d", env_net.service);
    }
    xSemaphoreGive(env_net.sem_send);
    return ret;
//    xSemaphoreTake(env_net.sem_send,portMAX_DELAY);
//    if (env_net.device == DRV_NET_DEVICE_BC26) {
//        if (env_net.service == DRV_NET_SERVICE_CM) {
//            ret = drv_bc26_cm_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else if (env_net.service == DRV_NET_SERVICE_CT) {
//            ret = drv_bc26_ct_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else if (env_net.service == DRV_NET_SERVICE_TCP) {
//            ret = drv_bc26_socket_connect(0, DRV_NET_SOCKET_TCP, env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else if (env_net.service == DRV_NET_SERVICE_UDP) {
//            ret = drv_bc26_socket_connect(0, DRV_NET_SOCKET_UDP, env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else {
//            ret = NET_ERR_UNKOWN;
//        }
//    } else if (env_net.device == DRV_NET_DEVICE_FT780) {
//        if (env_net.service == DRV_NET_SERVICE_CM) {
//            ret = drv_ft780_cm_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else if (env_net.service == DRV_NET_SERVICE_CT) {
////          ret = NET_ERR_UNKOWN;
//        } else if (env_net.service == DRV_NET_SERVICE_TCP) {
//            ret = drv_ft780_socket_connect(0,
//                                           DRV_NET_SOCKET_TCP,
//                                           env_net.pserver_ip,
//                                           env_net.pserver_port,
//                                           env_net.fifo_size);
//
//        } else if (env_net.service == DRV_NET_SERVICE_UDP) {
//            ret = drv_ft780_socket_connect(0,
//                                           DRV_NET_SOCKET_UDP,
//                                           env_net.pserver_ip,
//                                           env_net.pserver_port,
//                                           env_net.fifo_size);
//        } else {
//            ret = NET_ERR_UNKOWN;
//        }
//    }else if(env_net.device == DRV_NET_DEVICE_M5310A){
//        if (env_net.service == DRV_NET_SERVICE_CM) {
//            ret = drv_m5310a_cm_connect(env_net.pserver_ip, env_net.pserver_port, env_net.fifo_size);
//        } else if (env_net.service == DRV_NET_SERVICE_CT) {
////          ret = NET_ERR_UNKOWN;
//        } else if (env_net.service == DRV_NET_SERVICE_TCP) {
//            ret = drv_m5310a_socket_connect(0,
//                                           DRV_NET_SOCKET_TCP,
//                                           env_net.pserver_ip,
//                                           env_net.pserver_port,
//                                           env_net.fifo_size);
//
//        } else if (env_net.service == DRV_NET_SERVICE_UDP) {
//            ret = drv_m5310a_socket_connect(0,
//                                           DRV_NET_SOCKET_UDP,
//                                           env_net.pserver_ip,
//                                           env_net.pserver_port,
//                                           env_net.fifo_size);
//        } else {
//            ret = NET_ERR_UNKOWN;
//        }
//    }
//    xSemaphoreGive(env_net.sem_send);
//    return ret;
}


NET_ERR_CODE drv_net_disconnect(void) {
    NET_ERR_CODE ret = NET_ERR_UNKOWN;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    if (env_net.service == DRV_NET_SERVICE_CM) {
        if (pif->pf_cm_disconnect) {
            ret = pif->pf_cm_disconnect();
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if (env_net.service == DRV_NET_SERVICE_CT) {
        if (pif->pf_ct_disconnect) {
            ret = pif->pf_ct_disconnect();
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if ((env_net.service == DRV_NET_SERVICE_TCP) ||
               (env_net.service == DRV_NET_SERVICE_UDP)) {
        if (pif->pf_socket_disconnect) {
            ret = pif->pf_socket_disconnect(0);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else {
        NET_ERR("invalid service:%d", env_net.service);
    }
    xSemaphoreGive(env_net.sem_send);
    return ret;
//    NET_ERR_CODE ret = NET_ERR_UNKOWN;
//    xSemaphoreTake(env_net.sem_send,portMAX_DELAY);
//    if(env_net.device == DRV_NET_DEVICE_BC26){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//            ret = drv_bc26_cm_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
//            ret = drv_bc26_ct_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_bc26_socket_disconnect(0);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_bc26_socket_disconnect(0);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    } else if(env_net.device == DRV_NET_DEVICE_FT780){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//          ret = drv_ft780_cm_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
////          ret = drv_ft780_ct_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_ft780_socket_disconnect(0);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_ft780_socket_disconnect(0);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    } else if (env_net.device == DRV_NET_DEVICE_M5310A){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//            ret = drv_m5310a_cm_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
////          ret = drv_m5310a_ct_disconnect();
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_m5310a_socket_disconnect(0);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_m5310a_socket_disconnect(0);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    }
//    xSemaphoreGive(env_net.sem_send);
//  return ret;
}


NET_ERR_CODE drv_net_send(uint8_t *pdata, uint32_t len) {
    NET_ERR_CODE ret = NET_ERR_UNKOWN;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    if (env_net.service == DRV_NET_SERVICE_CM) {
        if (pif->pf_cm_send) {
            ret = pif->pf_cm_send(pdata, len);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if (env_net.service == DRV_NET_SERVICE_CT) {
        if (pif->pf_ct_send) {
            ret = pif->pf_ct_send(pdata, len);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else if ((env_net.service == DRV_NET_SERVICE_TCP) ||
               (env_net.service == DRV_NET_SERVICE_UDP)) {
        if (pif->pf_socket_send) {
            ret = pif->pf_socket_send(0, pdata, len);
        } else {
            NET_ERR("device %d not support %d", env_net.device, env_net.service);
        }
    } else {
        NET_ERR("invalid service:%d", env_net.service);
    }
    xSemaphoreGive(env_net.sem_send);
    return ret;
//    NET_ERR_CODE ret = NET_ERR_UNKOWN;
//    xSemaphoreTake(env_net.sem_send,portMAX_DELAY);
//    if(env_net.device == DRV_NET_DEVICE_BC26){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//            ret = drv_bc26_cm_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
//            ret = drv_bc26_ct_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_bc26_socket_send(0,pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_bc26_socket_send(0,pdata,len);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    }else if(env_net.device == DRV_NET_DEVICE_FT780){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//            ret = drv_ft780_cm_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
////          ret = drv_ft780_ct_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_ft780_socket_send(0,pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_ft780_socket_send(0,pdata,len);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    } else if (env_net.device == DRV_NET_DEVICE_M5310A){
//        if(env_net.service == DRV_NET_SERVICE_CM){
//            ret = drv_m5310a_cm_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_CT){
////          ret = drv_m5310a_ct_send(pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_TCP){
//            ret = drv_m5310a_socket_send(0,pdata,len);
//        }else if(env_net.service == DRV_NET_SERVICE_UDP){
//            ret = drv_m5310a_socket_send(0,pdata,len);
//        }else{
//            ret = NET_ERR_UNKOWN;
//        }
//    }
//    xSemaphoreGive(env_net.sem_send);
//    return ret;
}


NET_ERR_CODE drv_net_socket_connect(int32_t socket,
                                    DRV_NET_SOCKET_TYPE service_type,
                                    char *pstr_ip,
                                    char *pstr_port,
                                    uint32_t fifo_size) {
    NET_ERR_CODE ret;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    if (!BETWEEN00(0, socket, DRV_NET_MAX_NUM_OF_CONNECTIONS)) {
        NET_ERR("invalid socket %d", socket);
        return NET_ERR_UNKOWN;
    }
    if ((service_type != DRV_NET_SOCKET_TCP) && (service_type != DRV_NET_SOCKET_UDP)) {
        NET_ERR("invalid socket type %d", service_type);
        return NET_ERR_UNKOWN;
    }
    if (pstr_ip == NULL || pstr_port == NULL) {
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    ret = pif->pf_socket_connect(socket, service_type, pstr_ip, pstr_port, fifo_size);
    xSemaphoreGive(env_net.sem_send);
    return ret;
}


NET_ERR_CODE drv_net_socket_send(int32_t socket, uint8_t *pdata, uint32_t len) {
    NET_ERR_CODE ret;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    if (!BETWEEN00(0, socket, DRV_NET_MAX_NUM_OF_CONNECTIONS)) {
        NET_ERR("invalid socket %d", socket);
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    ret = pif->pf_socket_send(socket, pdata, len);
    xSemaphoreGive(env_net.sem_send);
    return ret;
}


NET_ERR_CODE drv_net_socket_disconnect(int32_t socket) {
    NET_ERR_CODE ret;
    const DRV_NET_INTERFACE *pif;
    pif = drv_net_find_if(env_net.device);
    if (pif == NULL) {
        NET_ERR("invalid device type:%d", env_net.device);
        return NET_ERR_UNKOWN;
    }
    if (!BETWEEN00(0, socket, DRV_NET_MAX_NUM_OF_CONNECTIONS)) {
        NET_ERR("invalid socket %d", socket);
        return NET_ERR_UNKOWN;
    }
    xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    if (env_net.state != NET_STATE_READY) {
        NET_ERR("net module is not ready");
        xSemaphoreGive(env_net.sem_send);
        return NET_ERR_UNKOWN;
    }
    ret  = pif->pf_socket_disconnect(socket);
    xSemaphoreGive(env_net.sem_send);
    return ret;
}


NET_ERR_CODE drv_net_recv_handler_set(int32_t socket, void (*pf_recv_handler)(uint8_t data)) {
    if (!BETWEEN10(0, socket, DRV_NET_MAX_NUM_OF_CONNECTIONS)) {
        NET_ERR("invalid socket %d", socket);
        return NET_ERR_UNKOWN;
    }
//  xSemaphoreTake(env_net.sem_send, portMAX_DELAY);
    env_net.pconns[socket].handler = pf_recv_handler;
//  xSemaphoreGive(env_net.sem_send);
    return NET_ERR_OK;
}

int32_t drv_net_write_bytes(uint8_t *pdata, uint32_t len) { 
    return drv_net_port_uart_write_bytes(pdata, len);
}


#if 0
NET_ERR_CODE drv_net_msg_at_recv(MSG_AT *pmsg_at, uint32_t times, uint32_t inteval, uint32_t num, ...) {
    uint32_t i;
    va_list pargs_cur;
    va_list pargs_head;
    va_start(pargs_head, num);
    for (; times > 0; times--) {
        pargs_cur = pargs_head; //move to head
        if (xQueueReceive(env_net.qinfo, pmsg_at, inteval) == pdPASS) {
            for (i = 0; i < num; i++) {
                if (va_arg(pargs_cur, AT_INFO) == pmsg_at->info) {
                    return NET_ERR_OK;
                } else {
                    NET_WAR("unexpected msg info%08x", pmsg_at->info);
                }
            }
        }
    }
    va_end(pargs_cur);
    return NET_ERR_UNKOWN;
}
#endif

NET_ERR_CODE drv_net_msg_at_receive(AT_INFO at_info, uint32_t n_times, uint32_t interval, MSG_AT *pmsg_at, const char *pinf) {
    uint32_t i;
    for (i = n_times; i > 0; i--) {
        if (xQueueReceive(env_net.qinfo, pmsg_at, interval) == pdPASS) {
            if (pmsg_at->info == at_info) {
                return NET_ERR_OK;
            } else {
                NET_WAR("unexpected msg info %08x", pmsg_at->info);
            }
        }
        if (pinf != NULL) {
            NET_INF("%s%d...", pinf, i);
        }
    }
    NET_ERR("wait for info %08x timeout", at_info);
    return NET_ERR_UNKOWN;
}


// ren year or pin year
uint8_t drv_is_ren_year(uint32_t year)
{
	if ((year % 4 == 0 && year % 100 != 0) || 
	    (year % 400 == 0)) {
	    return 1;		
	}
	return 0;
}

uint32_t drv_check_input_net_date(NET_DATE_T t)
{
	if ((t.days < 1 || t.days > 31) || (t.hours > 24) ||
		(t.min > 60) || (t.month < 1 || t.month > 12) ||
		(t.sec > 60)) {
		NET_INF("date : %d/%d/%d : %d/%d/%d", t.year,t.month,t.days,t.hours,t.min,t.sec);
		return 1;
	}
	return 0;
}

// date -> sec
uint32_t drv_net_date_to_sec(NET_DATE_T t, uint32_t* total_sec) 
{
	uint32_t i;
	uint32_t days_total = 0;
	uint32_t sec_total  = 0;
	uint8_t  ren_month[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
	uint8_t  pin_mouth[12] = {31,28,31,30,31,30,31,31,30,31,30,31};

	if (drv_check_input_net_date(t)) {
		NET_ERR("net error input date");
		return 1;
	}
	for (i = 1970; i < t.year; i++) {
		if (drv_is_ren_year(i)) {
			days_total += 366;
		} else {
			days_total += 365;
		}
	}
	if (drv_is_ren_year(t.year)) {
		for (i = 0; t.month > 1 && i < (t.month - 1) && i < 12; i++) {
			days_total += ren_month[i];
		}
	} else {
		for (i = 0; t.month > 1 && i < (t.month - 1) && i < 12; i++) {
			days_total += pin_mouth[i];
		}
	}
	days_total += (t.days > 0 ? (t.days - 1) : 0);
	sec_total  += days_total * 3600 * 24 + t.hours * 3600 + t.min * 60 + t.sec;
	*total_sec  = sec_total;
	return 0;
}

// correct time +- h

void drv_net_date_correct(NET_DATE_T* t, int32_t h) {
	int32_t   hours = t->hours + h;
	uint32_t  days  = t->days;
	uint32_t  month = t->month;
	uint32_t  year  = t->year;
	uint8_t  ren_month[12] = { 31,29,31,30,31,30,31,31,30,31,30,31 };
	uint8_t  pin_mouth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (drv_check_input_net_date(*t)) {
		NET_ERR("net error input date");
		return;
	}
	if (hours >= 0 && hours < 24) {
		t->hours = hours;
		return;
	} else if (hours >= 24) {
		t->hours = hours % 24;
		days++;
	} else if (hours < 0) {
		t->hours = 24 + hours;
		days--;
	}
	if (days == 0) {
		if (month == 1) {
			year--;
			month = 12;
			days  = 31;
		} else if (month > 1 && month <= 12) {
			days  = (drv_is_ren_year(year) > 0 ? ren_month[month - 2] : pin_mouth[month - 2]);
			month--;
		} else {
			NET_ERR("ren month = %d", month);
			return;
		}
	} else if (days > (drv_is_ren_year(year) > 0 ? ren_month[month - 1] : pin_mouth[month - 1])) {
		if (month == 12) {
			year++;
			month = 1;
			days = 1;
		} else if (month < 12) {
			month++;
			days = 1;
		} else {
			NET_ERR("pin month = %d", month);
			return;
		}
	}
	t->year  = year;
	t->month = month;
	t->days  = days;
}


#if 0
void at_test(const char *pdata,uint32_t len,uint32_t time){
    drv_net_write_bytes((uint8_t *)pdata,len);
    vTaskDelay(time);
}
void drv_net_task_test(void *parg){
    SEGGER_RTT_printf(0, "net test start...\r\n");
    drv_net_power_on();
    at_test(CSTRING("AT\r"),500);
    at_test(CSTRING("AT\r"),500);
    at_test(CSTRING("AT\r"),500);
    at_test(CSTRING("AT\r"),500);
    at_test(CSTRING("ATE0\r"),1000);
    at_test(CSTRING("ATI\r"),1000);
//    at_test(CSTRING("AT+CPSMS=0\r"),1000);
    at_test(CSTRING("AT+SM=LOCK\r"),1000);
    at_test(CSTRING("AT+QSM=LOCK\r"),1000);
    at_test(CSTRING("AT+CESQ\r"),1000);
    at_test(CSTRING("AT+CGATT?\r"),1000);
    at_test(CSTRING("AT+QGACT=1,1,\"CMNBIOT\"\r"),1000);
    at_test(CSTRING("AT+CGPADDR\r"),1000);
    while(1){
        at_test(CSTRING("AT+CESQ\r"),1000);
        at_test(CSTRING("AT+CGPADDR\r"),1000);
        at_test(CSTRING("AT+CGSN=1\r"),1000);
        at_test(CSTRING("AT+CIMI\r"),1000);
    }

    SEGGER_RTT_printf(0, "net test0\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *,"AT\r"));vTaskDelay(500);
    SEGGER_RTT_printf(0, "net test0\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *,"AT\r"));vTaskDelay(500);
    SEGGER_RTT_printf(0, "net test1\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *,"AT+SM=LOCK\r"));vTaskDelay(1000);
    SEGGER_RTT_printf(0, "net test2\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *,"AT+QSM=LOCK\r"));vTaskDelay(1000);
    SEGGER_RTT_printf(0, "net test3\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *, "AT+QGACT=1,1,\"CMNBIOT\"\r"));vTaskDelay(1000);
    SEGGER_RTT_printf(0, "net test4\r\n");
    drv_net_write_bytes(TSTRING(uint8_t *,"AT+CPIN?\r"));vTaskDelay(1000);
    SEGGER_RTT_printf(0, "net test5\r\n");
    while(1){

        drv_net_write_bytes(TSTRING(uint8_t *,"AT+CESQ\r"));
//        SEGGER_RTT_printf(0, "net test\r\n");
        vTaskDelay(1000);
        drv_net_write_bytes(TSTRING(uint8_t *,"AT+CGPADDR\r"));
//        SEGGER_RTT_printf(0, "net test\r\n");
        vTaskDelay(1000);
        drv_net_write_bytes(TSTRING(uint8_t *,"AT+CGSN=1\r"));
        vTaskDelay(1000);
    }
}
#endif

#if 0
//#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 1024
static app_fifo_t m_rx_fifo;
void rtt_init(void) {
    static uint8_t prx_buf[1024];
    ret_code_t err_code = app_fifo_init(&m_rx_fifo, prx_buf, sizeof(prx_buf));
    if (err_code != FIFO_SUCCESS) {
        return;
    }
}
void rtt_recv_task(void *parg) {
    size_t cnt;
    size_t i;
    static uint8_t pbuf[64];
    while (1) {
        cnt = SEGGER_RTT_Read(0, pbuf, sizeof(pbuf));
        if (cnt == 0) {
            vTaskDelay(30);
            continue;
        }
        for (i = 0; i < cnt; i++) {
            app_fifo_put(&m_rx_fifo, pbuf[i]);
        }
    }
}


void recv_handler_socket0(uint8_t data) {
    show_one_data(data);
}

static uint8_t ptest_buf[] = { 'A', 'A', 'B' };
static uint8_t ptest_buf1[] = { 'B', 'B', 'B' };
char task_list[1024];
void rtt_test_task(void *parg) {


//  drv_net_configure(DRV_NET_DEVICE_FT780,
//                    DRV_NET_CARRIER_CT,
//                    DRV_NET_SERVICE_CT,
//                    "180.101.147.115",
//                    "5683",
//                    1024);

//  drv_net_configure(DRV_NET_DEVICE_FT780,
//                    DRV_NET_CARRIER_CM,
//                    DRV_NET_SERVICE_CM,
//                    "183.230.40.39",
//                    "5683",
//                    1024);

//  drv_net_configure(DRV_NET_DEVICE_FT780,
//                    DRV_NET_CARRIER_CM,
//                    DRV_NET_SERVICE_TCP,
//                    NULL,
//                    NULL,
//                    1024);
    vTaskDelay(1000);
    vTaskList(task_list);
    NET_INF("---------task list-----------\n%s", task_list);
    drv_net_power_set(NET_POWER_ON);
//    drv_net_power_set(NET_POWER_ON);
//  drv_net_power_set(NET_POWER_SLEEP);
//  drv_net_power_set(NET_POWER_SLEEP);

//    drv_net_recv_handler_set(0, recv_handler_socket0);

//    drv_net_power_set(NET_POWER_ON);

//  drv_net_configure(DRV_NET_SERVICE_UDP,
//                    "59.174.243.135",
//                    "161",
//                    1024);
//  drv_net_configure(DRV_NET_SERVICE_UDP,
//                    "59.174.243.135",
//                    "161",
//                    1024);

    drv_net_configure(DRV_NET_SERVICE_CM,
                      NULL,
                      NULL,
                      1024);

//  drv_net_configure(DRV_NET_SERVICE_CT,
//                    NULL,
//                    NULL,
//                    1024);

//  drv_net_configure(DRV_NET_SERVICE_TCP,
//                    "106.12.192.105",
//                    "8080",
//                    1024);

    drv_net_connect();

//  drv_net_power_set(NET_POWER_SLEEP);
//  drv_net_power_set(NET_POWER_WAKE);
//  drv_net_recv_handler_set(0, recv_handler_socket0);
    drv_net_send(ptest_buf, sizeof(ptest_buf));
//
//  drv_net_send(ptest_buf1, sizeof(ptest_buf1));
//   drv_net_disconnect();
//    vTaskDelay(30000);
//    drv_net_disconnect();
    
    while (1) {
//      drv_net_send(ptest_buf,sizeof(ptest_buf));
//      vTaskDelay(20000);



//    uint32_t sq;
//      char *pimxi;
//    NET_INF("ret=%d", drv_net_sq_get(&sq));
//    NET_INF(".....sq:%d",sq);
//      pimxi = drv_net_imei_get();
//      if (pimxi) {
//          NET_INF(".....imei:%s",pimxi);
//      }else{
//          NET_ERR("failed to read imei");
//      }
//      pimxi = drv_net_imsi_get();
//      if (pimxi) {
//          NET_INF(".....imsi:%s",pimxi);
//      }else{
//          NET_ERR("failed to read imsi");
//      }
        /*****************************************************************/
      drv_net_power_set(NET_POWER_SLEEP);
      vTaskDelay(5000);
      drv_net_power_set(NET_POWER_WAKE);
      uint32_t i;
      for (i = 0;i < 10;i++) {
          NET_INF("wait%d...",i);
          vTaskDelay(1000);
      }
//  drv_net_connect();
      drv_net_send(ptest_buf, sizeof(ptest_buf));
        NET_INF("balabala...");
        vTaskDelay(1000);
//    vTaskDelay(2000);
//    drv_net_send(ptest_buf1, sizeof(ptest_buf1));
//    vTaskDelay(20000);
//      drv_net_power_set(NET_POWER_SLEEP);
//      drv_net_power_set(NET_POWER_WAKE);
    }
}
#endif








